﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

public class ResPrepareUtils
{
    #region 资源检测

    [MenuItem("Assets/资源预处理/资源路径校验/人物")]
    static void CheckCharacterResPath()
    {
        CheckResPath(PathUtils.HeroResPath);
    }

    [MenuItem("Assets/资源预处理/资源路径校验/特效")]
    static void CheckEffectResPath()
    {
        CheckResPath(PathUtils.EffectResPath);
    }

    static void CheckResPath(string resPath)
    {
        var objs = Selection.objects;

        for (int i = 0; i < objs.Length; i++)
        {
            string assetPath = AssetDatabase.GetAssetPath(objs[i]);
            string fileName = Path.GetFileName(assetPath);
            if (fileName.EndsWith(AssetPathUtils.prefabExtension))
            {
                if (!assetPath.Contains(resPath))
                {
                    Debug.Log("文件" + assetPath + "不在" + resPath + "目录下");
                    break;
                }
                string indexName = GetIndexName(assetPath);


                string[] assetDependencies = AssetDatabase.GetDependencies(assetPath);
                for (int j = 0; j < assetDependencies.Length; j++)
                {
                    if (assetDependencies[j].Contains(AssetPathUtils.LookDevStr))
                    {
                        continue;
                    }
                    string subFileName = Path.GetFileName(assetPath);
                    string parentDirName = AssetPathUtils.GetAssetDirectoryName(fileName);
                    if (!string.IsNullOrEmpty(parentDirName))
                    {
                        ResType resType = fileName.StartsWith(AssetPathUtils.effStr) ? ResType.Effect : ResType.Character;
                        string dirName = Path.GetDirectoryName(assetPath).Replace("\\", "/");

                        HandleRes(resType, assetDependencies[j], dirName, indexName, parentDirName);
                    }
                }
            }
        }

        Debug.Log("资源校验结束");
    }

    static void MoveObjToTargetPath(string assetPath, string originDirName, string targetDirName)
    {
        if (originDirName != targetDirName)
        {
            string dirPath = Application.dataPath.Replace("Assets", "") + targetDirName;
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
                AssetDatabase.Refresh();
            }

            AssetDatabase.MoveAsset(assetPath, assetPath.Replace(originDirName, targetDirName));
            Debug.LogError(assetPath + "位置异常");
        }
    }

    static void HandleRes(ResType resType, string assetPath, string dirName, string indexName, string assetPathName)
    {
        string formatStr;
        string resStr = "mod";
        string resPathStr = PathUtils.HeroResPath;
        string targetPath;

        if (resType == ResType.Effect)
        {
            resStr = "eff";
            resPathStr = PathUtils.EffectResPath;
        }

        if (assetPath.Contains(AssetPathUtils.CommonStr.ToLower()))
        {
            formatStr = "{0}/{1}/{2}";
            targetPath = string.Format(formatStr, resPathStr, AssetPathUtils.CommonStr, assetPathName);
        }
        else
        {
            formatStr = "{0}/{1}_{2}/{3}";
            targetPath = string.Format(formatStr, resPathStr, resStr, indexName, assetPathName);
        }

        MoveObjToTargetPath(assetPath, dirName, targetPath);
    }

    #endregion

    #region 人物资源

    [MenuItem("Assets/资源预处理/人物相关/01_人物动画资源导出",priority = 1)]
    static void ExportCharacterAnimations()
    {
        var objs = Selection.objects;
        for (int i = 0; i < objs.Length; i++)
        {
            string assetPath = AssetDatabase.GetAssetPath(objs[i]);
            ExportAnimation(assetPath);
        }
    }

    static void ExportAnimation(string assetPath, bool isAuto = false)
    {
        ModelImporter importer = (ModelImporter)ModelImporter.GetAtPath(assetPath);
        string dirPath = Path.GetDirectoryName(assetPath);
        UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
        for (int j = 0; j < assets.Length; j++)
        {
            var animationClip = assets[j];
            if (typeof(AnimationClip) == animationClip?.GetType()
                && !animationClip.name.Contains("preview"))
            {
                if (isAuto)
                {
                    importer.animationRotationError = 10;
                    importer.animationPositionError = 50;
                    importer.animationCompression = ModelImporterAnimationCompression.Optimal;
                }

                UnityEngine.Object newAnimationClip = new AnimationClip();
                EditorUtility.CopySerialized(animationClip, newAnimationClip);
                newAnimationClip.name = Path.GetFileNameWithoutExtension(assetPath);
                string animationPath = Path.Combine(dirPath, newAnimationClip.name + ".anim");
                Debug.Log(animationPath);
                AssetDatabase.CreateAsset(newAnimationClip, animationPath);
            }
        }
    }


    [MenuItem("Assets/资源预处理/人物相关/02_一键设置角色资源", priority = 2)]
    static void PrepareCharacterRes()
    {
        var model = Selection.activeObject;

        string assetPath = AssetDatabase.GetAssetPath(model);
        ModelImporter importer = (ModelImporter)ModelImporter.GetAtPath(assetPath);

        importer.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel;
        importer.optimizeGameObjects = true;

        importer.SearchAndRemapMaterials(ModelImporterMaterialName.BasedOnMaterialName, ModelImporterMaterialSearch.Everywhere);

        string frontStr = Application.dataPath.Replace("Assets", "");
        string[] files = Directory.GetFiles(frontStr + Path.GetDirectoryName(assetPath) + "/Animations");
        for (int i = 0; i < files.Length; i++)
        {
            if (Path.GetExtension(files[i]).ToLower() == AssetPathUtils.modelExtension)
            {
                ExportAnimation(files[i].Replace(frontStr, ""), true);
            }
        }
        var indexName = GetIndexName(assetPath);

        var go = PrefabUtility.InstantiatePrefab(model) as GameObject;
        string prefabPath = PathUtils.HeroResPath + "/mod_" + indexName + "/mod_" + indexName + ".prefab";
        SLCommon.CommonUtils.CreateDirWhenNotExist(PathUtils.HeroResPath);
        PrefabUtility.SaveAsPrefabAsset(go, prefabPath);

        GameObject.DestroyImmediate(go);
    }


    #endregion


    [MenuItem("Assets/资源预处理/特效相关/特效模型清理Unity默认材质")]
    private static void ClearUnityOriginMat()
    {
        //Material emptyMat = AssetDatabase.LoadAssetAtPath<Material>("Assets/Arts/Common/Empty.mat");

        var objs = Selection.objects;
        for (int i = 0; i < objs.Length; i++)
        {
            string assetPath = AssetDatabase.GetAssetPath(objs[i]);
            ModelImporter modelImporter = (ModelImporter)ModelImporter.GetAtPath(assetPath);
            modelImporter.materialImportMode = ModelImporterMaterialImportMode.ImportViaMaterialDescription;
            modelImporter.SearchAndRemapMaterials(ModelImporterMaterialName.BasedOnMaterialName, ModelImporterMaterialSearch.Everywhere);
        }
    }


    [MenuItem("Assets/资源预处理/场景环境光缓存")]
    private static void SaveSceneLight()
    {
        SceneAsset scene = Selection.activeObject as SceneAsset;
        if (scene != null)
        {
            SceneConfig sceneConfig = new SceneConfig();
            sceneConfig.Tag = scene.name;
            sceneConfig.Skybox = RenderSettings.skybox;
            sceneConfig.SkyLightColor = RenderSettings.ambientSkyColor;
            sceneConfig.skyLightInstensity = RenderSettings.ambientIntensity;

            string path = "Assets/Arts/Scenes/" + scene.name + "/" + scene.name + "Config.asset";
            AssetDatabase.DeleteAsset(path);
            AssetDatabase.CreateAsset(sceneConfig, path);
        }
        else
        {
            DebugUtils.LogError("请选中Scene");
        }
    }

    public static string GetIndexName(string assetPath)
    {
        string[] subs = Path.GetFileNameWithoutExtension(assetPath).Split("_");
        string indexName = subs[1] + "_" + subs[2];
        return indexName;
    }
}
